package com.divemotor.ventarepuestosinternet.dao.impl;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.sql.JoinType;
import org.primefaces.model.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.divemotor.ventarepuestosinternet.dao.CotizacionDAO;
import com.divemotor.ventarepuestosinternet.model.Cotizacion;
import com.divemotor.ventarepuestosinternet.model.EstadoCotizacion;
import com.divemotor.ventarepuestosinternet.model.Sucursal;
import com.divemotor.ventarepuestosinternet.model.Supervisor;
import com.divemotor.ventarepuestosinternet.model.Usuario;
import com.divemotor.ventarepuestosinternet.model.Vendedor;
import com.divemotor.ventarepuestosinternet.util.Constantes;
import com.divemotor.ventarepuestosinternet.util.DatosDeSession;

@SuppressWarnings("unchecked")
@Repository(value = "cotizacionDAO")
public class CotizacionDAOImpl implements CotizacionDAO {

	@Autowired
	private SessionFactory sessionFactory;

	@Override
	public Cotizacion guardar(Cotizacion cotizacion) {
		sessionFactory.getCurrentSession().persist(cotizacion);
		return cotizacion;
	}

	@Override
	public List<Cotizacion> buscar(Cotizacion cotizacion,
			Date fechaDesde, Date fechaHasta) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
				Cotizacion.class, "cotizacion");
		criteria.createAlias("cotizacion.sucursal", "sucursal");
		criteria.createAlias("cotizacion.usuarioCliente", "usuarioCliente");
		criteria.createAlias("usuarioCliente.usuario", "usuario");
		criteria.createAlias("cotizacion.estadoCotizacion", "estadoCotizacion");
		if (fechaDesde != null) {
			criteria.add(Restrictions
					.ge("cotizacion.fechaCreacion", fechaDesde));
		}
		if (fechaHasta != null) {
			criteria.add(Restrictions
					.le("cotizacion.fechaCreacion", fechaHasta));
		}
		if (cotizacion.getSucursal() != null && !cotizacion.getSucursal().getIdSucursal().equals(Constantes.NO_SELECCIONADO)) {
			criteria.add(Restrictions.eq("sucursal.idSucursal", cotizacion
					.getSucursal().getIdSucursal()));
		}

		if (cotizacion.getEstadoCotizacion()!=null && !cotizacion.getEstadoCotizacion().getIdEstadoCotizacion().equals(Constantes.NO_SELECCIONADO)) {
			criteria.add(Restrictions.eq("estadoCotizacion.idEstadoCotizacion",
					cotizacion.getEstadoCotizacion().getIdEstadoCotizacion()));
		}
		if(cotizacion.getUsuarioCliente()!=null){
			 criteria.add(Restrictions.eq("usuario.idUsuario",cotizacion.getUsuarioCliente().getUsuario().getIdUsuario()));
		}

		return criteria.list();
	}

	@Override
	public List<Cotizacion> listarPorUsuario(Usuario usuario) {
		return sessionFactory.getCurrentSession().createQuery("SELECT c from Cotizacion c " +
														"WHERE c.usuarioCliente.usuario.idUsuario=:idUsuario")
														.setParameter("idUsuario", usuario.getIdUsuario())
														.list();
	}

	
	
        @Override
	public Cotizacion obtenerPorId(Cotizacion cotizacion) {
		return (Cotizacion) sessionFactory.getCurrentSession().get(Cotizacion.class, cotizacion.getIdCotizacion());
	}

	
	@Override	
	public List<Cotizacion> listar() {
		Criteria  criteria = sessionFactory.getCurrentSession().createCriteria(Cotizacion.class);
		
		return criteria.list();
				
	}

	@Override
	public List<Cotizacion> listarPorSupervisor(Supervisor supervisor) {
		
		Supervisor supervisorB = new Supervisor();
	  
		Criteria  criteria = sessionFactory.getCurrentSession().createCriteria(Supervisor.class);
		criteria.add(Restrictions.eq("usuario", supervisor.getUsuario()));
		criteria.add(Restrictions.not(Restrictions.eq("estado", Constantes.ESTADO_ELIMINADO)));
		supervisorB = (Supervisor)criteria.uniqueResult();
		
		if(supervisorB.getListaSucursal().size() > 0 || supervisorB.getListaSucursal() == null ){
			Criteria criteria2 = sessionFactory.getCurrentSession().createCriteria(Cotizacion.class,"cotizacion");
			criteria2.createAlias("cotizacion.sucursal","sucursal");
			criteria2.add(Restrictions.in("sucursal",supervisorB.getListaSucursal()));
			return criteria2.list();
		}else{
			return null;
		}
	}

	@Override
	public List<EstadoCotizacion> obtenerEstadosCotizacionPorUsuarioSucursal(Usuario usuarioAutenticado) {
	    Criteria  criteria = sessionFactory.getCurrentSession().createCriteria(EstadoCotizacion.class);
		return criteria.list();
	}

	@Override
	public List<Vendedor> obtenerVendedoresPorUsuarioSucursal(
			Usuario usuarioAutenticado) {
		Supervisor supervisorB = new Supervisor();
		  
	    Criteria  criteria = sessionFactory.getCurrentSession().createCriteria(Supervisor.class);
	    criteria.add(Restrictions.eq("usuario", usuarioAutenticado));
	    criteria.add(Restrictions.not(Restrictions.eq("estado", Constantes.ESTADO_ELIMINADO)));
	    supervisorB = (Supervisor)criteria.uniqueResult();
	
	    if(supervisorB.getListaSucursal().size() > 0 || supervisorB.getListaSucursal() == null ){
			Criteria criteria2 = sessionFactory.getCurrentSession().createCriteria(Cotizacion.class,"cotizacion");
			criteria2.createAlias("cotizacion.sucursal","sucursal");
			criteria2.createAlias("cotizacion.vendedor","vendedor");
			criteria2.setProjection(Projections.distinct(Projections.property("vendedor")));
			criteria2.add(Restrictions.in("sucursal",supervisorB.getListaSucursal()));
			return criteria2.list();
		}else{
			return null;
		}
	}

	@Override
	public List<Cotizacion> buscar(int first, int pageSize,
			SortOrder sortOrder, String sortField, Date fechaInicio,
			Date fechaFin, String numeroSolicitudBuscar,
			Integer idDepartamentoBuscar, Integer idProvinciaBuscar,
			Integer idDistritoBuscar, Integer idSucursalBuscar,
			Integer idEstadoCotizacionBuscar, Integer idVendedorBuscar, List<Sucursal> listaSucursalesPermitidas) {					
		
		if(listaSucursalesPermitidas != null && listaSucursalesPermitidas.size() > 0){
	    
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Cotizacion.class,"cotizacion");
		criteria.createAlias("cotizacion.sucursal","sucursal");
		criteria.createAlias("sucursal.departamento","departamento"); 
		criteria.createAlias("sucursal.provincia", "provincia");
		criteria.createAlias("sucursal.distrito", "distrito");
		criteria.createAlias("cotizacion.estadoCotizacion", "estadoCotizacion");
		criteria.createAlias("cotizacion.vendedor", "vendedor",JoinType.LEFT_OUTER_JOIN);
		criteria.createAlias("vendedor.usuario", "usuario",JoinType.LEFT_OUTER_JOIN);	
		criteria.createAlias("cotizacion.usuarioCliente", "usuarioCliente");
		criteria.createAlias("usuarioCliente.cliente", "cliente");
				
        if(!(numeroSolicitudBuscar.equals(""))){
           criteria.add(Restrictions.eq("cotizacion.idCotizacion", Integer.parseInt(numeroSolicitudBuscar)));	
        }
        
		if(!(idDepartamentoBuscar.equals(Constantes.NO_SELECCIONADO))){
		  
		  criteria.add(Restrictions.eq("departamento.idDepartamento", idDepartamentoBuscar));	
		}
		
		if(!(idProvinciaBuscar.equals(Constantes.NO_SELECCIONADO))){
			
			criteria.add(Restrictions.eq("provincia.idProvincia", idProvinciaBuscar));
		}
		if (!(idDistritoBuscar.equals(Constantes.NO_SELECCIONADO))){
		
			criteria.add(Restrictions.eq("distrito.idDistrito", idDistritoBuscar));
		}
		if (!(idSucursalBuscar.equals(Constantes.NO_SELECCIONADO))){
			
			criteria.add(Restrictions.eq("sucursal.idSucursal", idSucursalBuscar));
		}
		if (!(idEstadoCotizacionBuscar.equals(Constantes.NO_SELECCIONADO))) {
		
			criteria.add(Restrictions.eq("estadoCotizacion.idEstadoCotizacion", idEstadoCotizacionBuscar));
		}
		
		if(!(idVendedorBuscar.equals(Constantes.NO_SELECCIONADO))){
			
			criteria.add(Restrictions.eq("vendedor.idVendedor",idVendedorBuscar));
		}
		
		criteria.add(Restrictions.in("sucursal", listaSucursalesPermitidas));
		
		if ((fechaInicio != null) && (fechaFin != null)) {
			criteria.add(Restrictions.between("cotizacion.fechaCreacion", fechaInicio, fechaFin));
		} else if ((fechaInicio != null) && (fechaFin == null)) {
			criteria.add(Restrictions.ge("cotizacion.fechaCreacion", fechaInicio));
		} else if ((fechaInicio == null) && (fechaFin != null)) {
			criteria.add(Restrictions.le("cotizacion.fechaCreacion", fechaFin));
		}
		
		criteria.setFirstResult(first);
		criteria.setMaxResults(pageSize);
		

		if (!(sortField == null)){
			if (sortOrder.toString().equals("ASCENDING"))
				criteria.addOrder(Order.asc(sortField.toString()));
				else{
					criteria.addOrder(Order.desc(sortField.toString()));
				}	
		}else{
			criteria.addOrder(Order.asc("idCotizacion")); //agregado
		}
		
		return criteria.list();
		}else{
			return null;
		}
	

	}

	@Override
	public int cantidadCotizaciones(Date fechaInicio, Date fechaFin,
			String numeroSolicitudBuscar, Integer idDepartamentoBuscar,
			Integer idProvinciaBuscar, Integer idDistritoBuscar,
			Integer idSucursalBuscar, Integer idEstadoCotizacionBuscar,
			Integer idVendedorBuscar, List<Sucursal> listaSucursalesPermitidas) {
		 
		if(listaSucursalesPermitidas != null && listaSucursalesPermitidas.size() > 0){
		
	     	Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Cotizacion.class,"cotizacion");
	     	criteria.createAlias("cotizacion.sucursal","sucursal");
			criteria.createAlias("sucursal.departamento","departamento"); 
			criteria.createAlias("sucursal.provincia", "provincia");
			criteria.createAlias("sucursal.distrito", "distrito");
			criteria.createAlias("cotizacion.estadoCotizacion", "estadoCotizacion");
			criteria.createAlias("cotizacion.vendedor", "vendedor",JoinType.LEFT_OUTER_JOIN);
			criteria.createAlias("vendedor.usuario", "usuario",JoinType.LEFT_OUTER_JOIN);
			
	        criteria.setProjection(Projections.count("cotizacion.idCotizacion"));
	        
	        if(!(numeroSolicitudBuscar.equals(""))){
	            criteria.add(Restrictions.eq("cotizacion.idCotizacion", Integer.parseInt(numeroSolicitudBuscar)));	
	         }
	         
	 		if(!(idDepartamentoBuscar.equals(Constantes.NO_SELECCIONADO))){
	 		
	 		  criteria.add(Restrictions.eq("departamento.idDepartamento", idDepartamentoBuscar));	
	 		}
	 		
	 		if(!(idProvinciaBuscar.equals(Constantes.NO_SELECCIONADO))){
	 			
	 			criteria.add(Restrictions.eq("provincia.idProvincia", idProvinciaBuscar));
	 		}
	 		if (!(idDistritoBuscar.equals(Constantes.NO_SELECCIONADO))){
	 		
	 			criteria.add(Restrictions.eq("distrito.idDistrito", idDistritoBuscar));
	 		}
	 		if (!(idSucursalBuscar.equals(Constantes.NO_SELECCIONADO))){
	 		
	 			criteria.add(Restrictions.eq("sucursal.idSucursal", idSucursalBuscar));
	 		}
	 		if (!(idEstadoCotizacionBuscar.equals(Constantes.NO_SELECCIONADO))) {
	 		
	 			criteria.add(Restrictions.eq("estadoCotizacion.idEstadoCotizacion", idEstadoCotizacionBuscar));
	 		}
	 		
	 		if(!(idVendedorBuscar.equals(Constantes.NO_SELECCIONADO))){
	 			
	 			criteria.add(Restrictions.eq("vendedor.idVendedor",idVendedorBuscar));
	 		}
	 	
			criteria.add(Restrictions.in("sucursal", listaSucursalesPermitidas));
	        
			if ((fechaInicio != null) && (fechaFin != null)) {
				criteria.add(Restrictions.between("cotizacion.fechaCreacion", fechaInicio, fechaFin));
			} else if ((fechaInicio != null) && (fechaFin == null)) {
				criteria.add(Restrictions.ge("cotizacion.fechaCreacion", fechaInicio));
			} else if ((fechaInicio == null) && (fechaFin != null)) {
				criteria.add(Restrictions.le("cotizacion.fechaCreacion", fechaFin));
			}
			
			Number result = (Number) criteria.uniqueResult();
			return result.intValue();
		}else{
			return 0;
		}
	}

	@Override
	public int cantidadCotizaciones() {
		Supervisor supervisorB = new Supervisor();
		  
		Criteria  criteria2 = sessionFactory.getCurrentSession().createCriteria(Supervisor.class);
		criteria2.add(Restrictions.eq("usuario", DatosDeSession.obtenerUsuarioAutenticado()));
		criteria2.add(Restrictions.not(Restrictions.eq("estado", Constantes.ESTADO_ELIMINADO)));
		supervisorB = (Supervisor)criteria2.uniqueResult();
		
		if(supervisorB.getListaSucursal().size() > 0 || supervisorB.getListaSucursal() == null ){
           Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Cotizacion.class,"cotizacion");
	       criteria.setProjection(Projections.count("cotizacion.idCotizacion"));
	       criteria.createAlias("cotizacion.sucursal", "sucursalPermitidas");
		   criteria.add(Restrictions.in("sucursal",supervisorB.getListaSucursal()));
       	   Number result = (Number) criteria.uniqueResult();
		   return result.intValue();
		}else{
		   return 0;
		}
	}

	@Override
	public void actualizar(Cotizacion cotizacion) {
		sessionFactory.getCurrentSession().merge(cotizacion);
		
	}

}
